IAM ポリシーの Conditions 句に aws:SourceIp と aws:VpcSourceIp を併記できるかを確認してみた。

IAM ポリシーの Conditions 句に aws:SourceIp と aws:VpcSourceIp を併記できるかを確認してみた。

IAM ポリシーの Conditions 句に aws:SourceIp と aws:VpcSourceIp を併記できることが分かりました。検証結果を記事にします。
Clock Icon2024.09.20

はじめに

猫とアポロチョコが好きな、アノテーション株式会社の m.hayakawa です。

IAM ポリシーに IAM アドレス制限を掛けたい場合があります。パブリック IP アドレスとプライベート IP アドレスを両方使いたい場合があります。例えば、S3 へファイルを転送する際はインターネットを経由させずに、VPC エンドポイントを経由させたいときなどが考えられます。

IP アドレスに関する条件は Condition 句を使用しますが、パブリック IP アドレスを評価する場合は aws:SourceIp 条件コンテキストキー、プライベート IP アドレスを評価する場合は aws:VpcSourceIp 条件コンテキストキーを使用します。

これを併記することはできるか、本記事にて検証していきます。

前提条件

Amazon Linux 2023 の EC2 インスタンスをパブリックサブネット上に作成します。

IAM ロール: EC2RoleForTest を作成します。信頼関係に EC2 サービスを追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Principal": {
                "Service": [
                    "ec2.amazonaws.com"
                ]
            }
        }
    ]
}

AWS 管理ポリシー: AdministratorAccess をアタッチします。

上記の IAM ロールを EC2 にアタッチします。

EC2 のパブリック IP は 35.78.2.29 とします(こちらは検証時に使用しており、すでに削除済みです)。

検証

パブリック IP アドレスで制御できるか

始めに、デフォルトの状態で AWS CLI コマンドを実行できるかをチェックします。

$ aws s3 ls
2024-08-13 04:10:06 test-bucket-blog

問題なく実行できます。

では、次にすべてのアクションを Deny するインラインポリシーを IAM ロールにアタッチします。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "AllDeny",
			"Effect": "Deny",
			"Action": "*",
			"Resource": "*"
		}
	]
}

当然、アクションは明示的に拒否されるので失敗します。

$ aws s3 ls

An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:sts::<AccountID>:assumed-role/EC2RoleForTest/i-01230123012301234 is not authorized to perform: s3:ListAllMyBuckets with an explicit deny in an identity-based policy

それでは、EC2 のパブリック IP: 35.78.2.29 を明示的な拒否から除外してみます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyNotIpAddress",
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "35.78.2.29/32"
                    ]
                }
            }
        }
    ]
}

AWS CLI コマンドが成功しました。

$ aws s3 ls
2024-08-13 04:10:06 test-bucket-blog

これにより、EC2 のパブリック IP を Condition 句に指定することで、特定の IP アドレスからのアクセスを可能にできることが分かります。

プライベート IP アドレスで制御できるか

プライベート IP で AWS 環境へアクセスするために、参考資料 [1] の記事を参考に VPC エンドポイントを作成していきます。

本記事では S3 インターフェースエンドポイントを用いて検証します。

S3 インターフェースエンドエンドポイント経由で明示的にアクセスする場合は、--endpoint-url オプションを使用します。

$ aws s3 ls --endpoint-url http://bucket.vpce-0123456789abcdef0-sample.s3.ap-northeast-1.vpce.amazonaws.com

An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:sts::<AccountID>:assumed-role/EC2RoleForTest/i-01230123012301234 is not authorized to perform: s3:ListAllMyBuckets with an explicit deny in an identity-based policy

明示的な拒否で失敗していることが分かりました。

インターフェースエンドポイントは VPC の CIDR の範囲で IP アドレスが割り当てられるため、IAM ポリシーにその IP アドレスを許可するように設定します。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyNotIpAddress2",
			"Effect": "Deny",
			"Action": "*",
			"Resource": "*",
			"Condition": {
				"NotIpAddress": {
					"aws:SourceIp": [
						"35.78.2.29/32"
					],
					"aws:VpcSourceIp": [
						"172.31.0.0/16"
					]
				}
			}
		}
	]
}

再度実行します。

$ aws s3 ls --endpoint-url http://bucket.vpce-0123456789abcdef0-sample.s3.ap-northeast-1.vpce.amazonaws.com
2024-08-13 04:10:06 test-bucket-blog

アクセスができることを確認しました。

補足(IAMポリシーの評価論理)

Condition 句内の、条件演算子(本記事では NotIpAddress)内に複数の条件コンテキストキー(本記事では、aws:SourceIp と aws:VpcSourceIp)がある場合、コンテキストキーは論理 AND を使用して評価されます。

この場合、パブリック IP アドレス 35.78.2.29/32 と プライベート IP アドレス 172.31.0.0/16 のどちらの値も一致しない場合、Deny されるという意味合いでの AND 評価となります。

参考資料

[1] インターフェイスVPCエンドポイント AWS サービス を使用して にアクセスする - Amazon Virtual Private Cloud

[2] Amazon S3 バケットアクセスを特定の IP または VPC に制限する | AWS re:Post

[3] 複数のコンテキストキーまたは値による条件 - AWS Identity and Access Management

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.